package cn.chiship.framework.common.config.resolver;

import cn.chiship.sdk.cache.service.UserCacheService;
import cn.chiship.sdk.cache.vo.CacheUserVO;
import cn.chiship.sdk.core.enums.BaseResultEnum;
import cn.chiship.sdk.core.enums.HeaderEnum;
import cn.chiship.sdk.core.exception.custom.AccessTokenException;
import cn.chiship.framework.common.annotation.LoginUser;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * @author lijian
 */
@Component
public class CurrentUserHandlerMethodArgResolver implements HandlerMethodArgumentResolver {

	/**
	 * 判断是否支持使用@CurrentUser注解的参数
	 */
	@Override
	public boolean supportsParameter(MethodParameter methodParameter) {
		/**
		 * 如果该参数注解有@CurrentUser且参数类型是User
		 */
		return methodParameter.getParameterAnnotation(LoginUser.class) != null
				&& methodParameter.getParameterType() == CacheUserVO.class;
	}

	/**
	 * 注入参数值
	 */
	@Override
	public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
			NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
		HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
		String token = request.getHeader(HeaderEnum.HEADER_ACCESS_TOKEN.getName());
		if (token == null) {
			throw new AccessTokenException(BaseResultEnum.HEADER_NO_TOKEN);
		}
		BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
		UserCacheService userCacheService = factory.getBean(UserCacheService.class);

		if (!userCacheService.isValid()) {
			throw new AccessTokenException(BaseResultEnum.ERROR_TOKEN);
		}
		return userCacheService.getUser();

	}

}
